#pragma once

#include <iostream>
#include <string>
#include <sstream>
#include <unistd.h>
#include <functional>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <unistd.h>
#include <ctime>

using namespace std;

static const uint16_t gport = 8080;
static const int gbacklog = 5; // 大于0，小于20，一般来说

class TcpServer
{
public:
    TcpServer(uint16_t port = gport)
        : _listensock(-1),
          _port(port)
    {
    }
    ~TcpServer()
    {
    }

public:
    void initServer()
    {
        // 1.创建套接字
        _listensock = socket(AF_INET, SOCK_STREAM, 0);
        if (_listensock < 0)
        {
            cout << "creat socket error" << endl;
            exit(1);
        }
        cout << "creat socket success" << endl;

        // 2.bind自己的网络信息
        struct sockaddr_in local;
        memset(&local, 0, sizeof(local));
        local.sin_family = AF_INET;
        local.sin_port = htons(_port);
        local.sin_addr.s_addr = INADDR_ANY; // 任意地址都能连我
        if (bind(_listensock, (struct sockaddr *)&local, sizeof(local)) < 0)
        {
            cout << "bind  socket error" << endl;
            exit(2);
        }
        cout << "bind socket success" << endl;

        // 设置sock为lisent监听状态
        if (listen(_listensock, gbacklog) < 0)
        {
            cout << "listen socket error" << endl;
        }
        cout << "listen socket success" << endl;
    }
    void start()
    {
        while (true)
        {
            // server获取线连接
            struct sockaddr_in peer;
            socklen_t peerlen = sizeof(peer);
            int sock = accept(_listensock, (struct sockaddr *)&peer, &peerlen);
            if (sock < 0)
            {
                cout << "accept error,next" << endl;
                sleep(1);
                continue;
            }
            else
            {
                cout << "accept a new line" << endl;
            }
            char buffer[1024];
            for (;;)
            {
                cout << "开始读取" << endl;

                string clientip = inet_ntoa(peer.sin_addr); // 1.网络序列 2.int->点分十进制IP
                uint16_t clientport = ntohs(peer.sin_port);
                ssize_t s = recv(sock, buffer, sizeof(buffer) - 1, 0);
                if (s > 0)
                {
                    buffer[s] = 0;
                    string message = buffer;
                    string err = "Send device anomaly event data";
                    if (message == err)
                    {
                        cout << "出问题啦，要给Client端返回消息！" << endl;
                        time_t now = time(0);      // 获取当前系统时间的秒数
                        tm *ltm = localtime(&now); // 转换为tm结构体
                        string nowTime = "";

                        // 输出年月日时分秒
                        nowTime += to_string(1900 + ltm->tm_year) + "/"
                                  + to_string(1 + ltm->tm_mon) + "/"
                                  + to_string(ltm->tm_mday) + " "
                                  + to_string(ltm->tm_hour) + ":"
                                  + to_string(ltm->tm_min) + ":"
                                  + to_string(ltm->tm_sec) + "\n";
                        nowTime += "数据异常，请立刻停止操作\n";
                        // 信息返给Client
                        if(send(sock,nowTime.c_str(),nowTime.size(),0) == -1)
                        cout << "Message send to Client error" << endl;
                        else
                        cout << "Message send to Client success" << endl;
                    }
                    cout << clientip << "[" << clientport << "]# " << message << endl;
                }
                else if (s == 0)
                {
                    cout << "client closed connection" << endl;
                    close(sock);
                    break;
                }
                else
                {
                    cout << "recv error" << endl;
                    close(sock);
                    break;
                }
                sleep(1);
            }
        }
    }

private:
    int _listensock;
    uint16_t _port;
};